#include <REGX52.h>

//引脚定义
sbit DS1302_IO = P3^4;		//数据输入/输出
sbit DS1302_CE = P3^5;		//使能
sbit DS1302_SCLK = P3^6;	//串行时钟上升沿，分隔相邻数据

//寄存器写入指令定义
#define DS1302_SECOND		0x80
#define DS1302_MINUTE		0x82
#define DS1302_HOUR			0x84
#define DS1302_DATE			0x86
#define DS1302_MOUTH		0x88
#define DS1302_DAY			0x8A
#define DS1302_YEAR			0x8C
//写保护寄存器
#define DS1302_WP			0x8E

//实时时钟初始时间
//							   24年11月2日11时59分55秒周6
unsigned char DS1302_Time[] = {24, 11, 2, 12, 59, 55, 6};

/**
  * @brief		初始化DS1302
  * @parm		无
  * @retval		无
  */
void DS1302_Init()
{
	DS1302_CE = 0;
	DS1302_SCLK = 0;
}

/**
  * @brief		往DS1302中写数据
  * @parm		Command: 写秒or分钟...		范围:0 ~ 255
  * @parm		Data:要写入的数据			范围:0 ~ 255
  * @retval		无
  */
void DS1302_WriteByte(unsigned char Command, unsigned char Data)
{
	int i = 0;
	//打开使能
	DS1302_CE = 1;
	//先写命令Command
	//8位数据, 从低位开始
	for(i = 0; i < 8; ++i)
	{
		DS1302_IO = Command & (0x01 << i);
		//给串行时钟上升沿
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	//再写数据，数据要由十进制转为BCD码
	Data = (Data / 10 * 16) + (Data % 10);
	for(i = 0; i < 8; ++i)
	{
		DS1302_IO = Data & (0x01 << i);
		//给串行时钟上升沿
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	DS1302_CE = 0;//使能复位
}
/**
  * @brief		DS1302读取数据
  * @parm		Command(命令字): 读秒or分钟...		范围:0 ~ 255
  * @retval		返回读到的数据						范围:0 ~ 255
  */
unsigned char DS1302_ReadByte(unsigned char Command)
{
	unsigned char Data = 0;
	int i = 0;
	//传入写指令，转化为读指令
	Command |= 0x01;
	DS1302_CE = 1;
	//8位数据, 从低位开始
	for(i = 0; i < 8; ++i)
	{
		DS1302_IO = Command & (0x01 << i);//注意这边只能先赋值再控制上升沿
		DS1302_SCLK = 0;
		DS1302_SCLK = 1;
	}
	//读数据
	for(i = 0; i < 8; ++i)
	{
		DS1302_SCLK = 1;
		//下降沿读数据
		DS1302_SCLK = 0;
		if(DS1302_IO)
			Data |= (0x01 << i);
	}
	DS1302_CE = 0;
	DS1302_IO = 0;	//读取后将IO设置为0，否则读出的数据会出错
	//读出的数据要由BCD码转为十进制
	Data = (Data / 16 * 10) + (Data % 16);
	return Data;
}
/**
  * @brief		将DS1302_Time的时间设置进DS1302
  * @parm		无
  * @retval		无
  */
void DS1302_SetTime()
{
	//关闭写保护
	DS1302_WriteByte(DS1302_WP, 0x00);
	DS1302_WriteByte(DS1302_YEAR, DS1302_Time[0]);//年
	DS1302_WriteByte(DS1302_MOUTH, DS1302_Time[1]);//月
	DS1302_WriteByte(DS1302_DATE, DS1302_Time[2]);//日
	DS1302_WriteByte(DS1302_HOUR, DS1302_Time[3]);//时
	DS1302_WriteByte(DS1302_MINUTE, DS1302_Time[4]);//分
	DS1302_WriteByte(DS1302_SECOND, DS1302_Time[5]);//秒
	DS1302_WriteByte(DS1302_DAY, DS1302_Time[6]);//周几
	//打开写保护
	DS1302_WriteByte(DS1302_WP, 0x80);
}

/**
  * @brief		读取次数DS1302时间，并设置到DS1302_Time数组中
  * @parm		无
  * @retval		无
  */
void DS1302_ReadTime()
{
	unsigned char tmp;
	tmp = DS1302_ReadByte(DS1302_YEAR);//年
	DS1302_Time[0] = tmp;
	
	tmp = DS1302_ReadByte(DS1302_MOUTH);//月
	DS1302_Time[1] = tmp;
	
	tmp = DS1302_ReadByte(DS1302_DATE);//日
	DS1302_Time[2] = tmp;
	
	tmp = DS1302_ReadByte(DS1302_HOUR);//时
	DS1302_Time[3] = tmp;
	
	tmp = DS1302_ReadByte(DS1302_MINUTE);//分
	DS1302_Time[4] = tmp;
	
	tmp = DS1302_ReadByte(DS1302_SECOND);//秒
	DS1302_Time[5] = tmp;
	
	tmp = DS1302_ReadByte(DS1302_DAY);//周几
	DS1302_Time[6] = tmp;
}


